<template>
	<!-- 播放器 -->
	<div
		class="playerContainer"
		ref="playerContainer"
		style="bottom: 0"
		:class="{ playPageActive: showPlaySongPage }">
		<div class="player container">
			<!-- 控制切歌 -->
			<div class="controls">
				<GoStart
					theme="filled"
					size="32"
					fill="#fff"
					class="iconfont pointer"
					@click="
						handleNextSong(plStore.currentPlaylist, player.currentSongInfo, 'previous')
					" />
				<Play
					v-show="!player.playStatus"
					theme="outline"
					size="38"
					fill="#fff"
					class="iconfont pointer"
					@click="handlePlayPause" />
				<PauseOne
					v-show="player.playStatus"
					theme="outline"
					size="38"
					fill="#fff"
					class="iconfont pointer"
					@click="handlePlayPause" />
				<GoEnd
					theme="filled"
					size="32"
					fill="#fff"
					class="iconfont pointer"
					@click="handleNextSong(plStore.currentPlaylist, player.currentSongInfo)" />
			</div>
			<!-- 歌曲封面 -->
			<div class="songCover pointer" @click="showPlayPage">
				<img :src="player.currentSongInfo.cover + '?param=50y50'" />
			</div>
			<!-- 播放进度 -->
			<div class="playProgress">
				<!-- 歌曲信息 -->
				<div class="songInfo">
					<div class="left textEllipsis">
						<!-- 歌曲名称 -->
						<span>{{ player.currentSongInfo.name }}</span>
						<span> - </span>
						<!-- 歌手列表 -->
						<span v-for="(item, index) in player.currentSongInfo.singers" :key="item.id">
							{{ item.name }}
							<span v-if="index !== player.currentSongInfo.singers.length - 1">、</span>
						</span>
					</div>
					<div class="right">
						<span>{{ currentTime }} / {{ player.currentSongInfo.duration }}</span>
					</div>
				</div>
				<!-- 进度条 -->
				<div class="progress">
					<div class="slider-demo-block" style="width: 100%">
						<el-slider
							v-model="progressValue"
							:show-tooltip="false"
							@change="dragProgressBar" />
					</div>
				</div>
			</div>
			<!-- 其他操作 -->
			<div class="otherControls">
				<!-- 操作列表 -->
				<div class="list">
					<!-- 收藏 -->
					<!-- 未收藏 -->
					<Like
						v-show="!faStore.favoriteStatus({ ...player.currentSongInfo })"
						@click="faStore.addFavorite({ ...player.currentSongInfo })"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						title="收藏" />
					<!-- 已收藏 -->
					<Like
						v-show="faStore.favoriteStatus({ ...player.currentSongInfo })"
						theme="filled"
						size="20"
						fill="#f00"
						@click.stop="faStore.addFavorite({ ...player.currentSongInfo })"
						class="iconfont pointer"
						title="收藏" />
					<!-- 播放顺序 -->
					<SortThree
						@click="changePlayOrder"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						title="顺序播放"
						v-show="currentOrder === '1'" />
					<ShuffleOne
						@click="changePlayOrder"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						title="随机播放"
						v-show="currentOrder === '2'" />
					<PlayOnce
						@click="changePlayOrder"
						theme="outline"
						size="24"
						fill="#fff"
						class="iconfont pointer"
						title="单曲循环"
						v-show="currentOrder === '3'" />
					<!-- 下载 -->
					<a :href="player.currentSongInfo.url" target="_blank">
						<Download
							theme="outline"
							size="20"
							fill="#fff"
							class="iconfont pointer"
							title="下载" />
					</a>
					<!-- 播放列表 -->
					<MusicList
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						title="播放列表"
						@click="plStore.showDrawer = !plStore.showDrawer" />
				</div>
				<!-- 音量 -->
				<div class="volume">
					<!-- 静音 -->
					<VolumeMute
						v-show="audioVolume === 0"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer" />
					<!-- 音量小 -->
					<VolumeSmall
						v-show="audioVolume < 60 && audioVolume > 0"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						@click="audioVolume = 0" />
					<!-- 音量大 -->
					<VolumeNotice
						v-show="audioVolume >= 60"
						theme="outline"
						size="20"
						fill="#fff"
						class="iconfont pointer"
						@click="audioVolume = 0" />
					<!-- 音量条 -->
					<div class="slider-demo-block" style="width: 50%; margin-left: 10px">
						<el-slider v-model="audioVolume" />
					</div>
				</div>
			</div>
			<!-- 音频可视化 -->
			<div class="audioView">
				<canvas ref="audioViewCanvas"></canvas>
			</div>
		</div>
		<!-- 显示/隐藏 -->
		<div
			class="showAndHidden pointer"
			@click="showAndHidden"
			:class="{ playPageActive: showPlaySongPage }">
			<Up
				theme="filled"
				size="24"
				fill="#fff"
				class="iconfont"
				:style="{
					transform: showState ? 'rotate(180deg)' : 'rotate(0)',
				}" />
		</div>
	</div>
	<!-- 播放页 -->
	<div
		class="playSongPage"
		ref="playSongPage"
		style="width: 0px; height: 0px; background-image: ''; opacity: 0">
		<!-- 关闭播放页 -->
		<div class="close pointer" title="关闭" @click="showPlayPage">
			<CloseSmall theme="outline" size="28" fill="#fff" class="iconfont" />
		</div>
		<!-- 模糊遮罩 -->
		<div class="mask"></div>
		<!-- 歌词 -->
		<div class="lyricContainer">
			<!-- 歌曲封面 -->
			<div class="songCover">
				<img :src="player.currentSongInfo.cover + '?param=300y300'" />
				<!-- 相似歌曲 -->
				<div class="similarSong">
					<h3>
						<span>相似歌曲</span>
						<PreviewOpen
							theme="outline"
							size="20"
							fill="#fff"
							class="iconfont pointer"
							v-show="showSimilarSong"
							@click="showSimilarSong = !showSimilarSong" />
						<PreviewClose
							theme="outline"
							size="20"
							fill="#fff"
							class="iconfont pointer"
							v-show="!showSimilarSong"
							@click="showSimilarSong = !showSimilarSong" />
					</h3>
					<ul v-show="showSimilarSong">
						<li
							class="pointer textEllipsis"
							v-for="item in player.simiSongList"
							:key="item.id"
							@click="playSong(item.id)">
							<img v-lazy="item.album.picUrl + '?param=50y50'" alt="logo" />
							<span class="name" :title="item.name">{{ item.name }}</span>
							<span> - </span>
							<span class="singers" v-for="(singer, index) in item.artists">
								<span :key="singer.id">{{ singer.name }}</span>
								<span v-if="index !== item.artists.length - 1">、</span>
							</span>
						</li>
					</ul>
				</div>
			</div>
			<!-- 唱片 -->
			<div class="disc" :class="{ discAnimationPaused: !player.playStatus }">
				<img :src="player.currentSongInfo.cover + '?param=160y160'" />
			</div>
			<!-- 歌曲信息 -->
			<div class="songInfoContainer">
				<div class="songInfo">
					<!-- 歌曲名称 -->
					<div class="songName textEllipsis" :title="player.currentSongInfo.name">
						{{ player.currentSongInfo.name }}
					</div>
					<!-- 专辑和歌手信息 -->
					<div class="singerAndAlbum">
						<div class="album floatLeft textEllipsis">
							<span :title="player.currentSongInfo.album">专辑：</span>
							{{ player.currentSongInfo.album }}
						</div>
						<div class="singers floatRight textEllipsis">
							<span>歌手：</span>
							<span
								v-for="(item, index) in player.currentSongInfo.singers"
								:key="item.id">
								{{ item.name }}
								<span v-if="index !== player.currentSongInfo.singers.length - 1">、</span>
							</span>
						</div>
					</div>
					<div class="lyricBox">
						<ul class="lyric">
							<li
								v-for="(line, index) in player.currentSongInfo.lyric"
								:class="{ lyricActive: currentLyric === index }"
								:key="index">
								{{ line.lyric }}
							</li>
						</ul>
					</div>
				</div>
			</div>
		</div>
	</div>
	<!-- 
        crossOrigin="anonymous" 解决跨域音频资源
     -->
	<audio
		@timeupdate="getSongCurrentProgress"
		style="display: none"
		ref="audio"
		preload="auto"
		autoplay
		crossOrigin="anonymous"
		:loop="currentOrder === '3'"></audio>
	<PlayList />
</template>

<script name="Player" setup>
import { ref, nextTick, watch, onMounted, computed, getCurrentInstance } from 'vue';
import {
	Up,
	GoStart,
	Play,
	GoEnd,
	VolumeNotice,
	VolumeMute,
	VolumeSmall,
	Download,
	MusicList,
	Like,
	PauseOne,
	CloseSmall,
	ShuffleOne,
	SortThree,
	PlayOnce,
	PreviewOpen,
	PreviewClose,
} from '@icon-park/vue-next'; // 图标库
import playerStore from '@/stores/playerStore';
import { formatAudioTime } from '@/utils/formatter';
import PlayList from '@/components/PlayList.vue';
import favoritesStore from '@/stores/favoritesStore';
import playlistStore from '@/stores/playlistStore';
import { usePlaySong } from '@/hooks/usePlaySong';
import { useAVCircle } from 'vue-audio-visual';
import playOrderStore from '@/stores/playOrderStore';
import { storeToRefs } from 'pinia';

const player = playerStore();
const faStore = favoritesStore();
const plStore = playlistStore();
const { playSong } = usePlaySong();
const { changePlayOrder } = playOrderStore();
const { currentOrder } = storeToRefs(playOrderStore());
const { proxy } = getCurrentInstance();

// 播放器 -> audio
let audio = ref(null); // 播放器
let audioVolume = ref(50);
let audioViewCanvas = ref(null);

// 音频可视化
useAVCircle(audio, audioViewCanvas, {
	src: player.currentSongInfo.url,
	canvHeight: 50,
	canvWidth: 50,
	barColor: '#409eff',
	outlineWidth: '0',
	playtimeColor: '#409eff',
	playtimeFont: 12,
	progressColor: '#DFF6F0',
});

// 播放暂停
function handlePlayPause() {
	if (player.currentSongInfo.url === null) return;
	// 判断歌曲是否处于播放状态
	if (!audio.value.paused) {
		audio.value.pause();
		player.changePlayStatus(false);
	} else {
		audio.value.play();
		player.changePlayStatus(true);
	}
}

// 显示相似歌曲
let showSimilarSong = ref(true);

// 空格暂停播放
window.addEventListener('keydown', (e) => {
	if (e.code === 'Space' || e.keyCode === 32) {
		handlePlayPause();
	}
});

let currentRandomIndex = null; // 当前随机播放的歌曲索引
let randomList = []; // 随机索引列表
/**
 * 下一首歌曲
 * @param { string } currentList 当前正在播放的歌曲列表
 * @param { object } currentSong 当前播放结束的歌曲
 * @param { string } type 操作类型 ['auto', 'next', 'previous']
 */
function handleNextSong(currentList, currentSong, type = 'next') {
	// 查找歌曲
	const index = currentList.findIndex((item) => item.id === currentSong.id);
	// 判断播放顺序
	if (currentOrder.value === '2' && type === 'next') {
		// 随机播放下一首
		let random = proxy.lodash.random(0, currentList.length); // 随机播放随机数
		while (true) {
			// 避免生成重复的随机数
			if (random === currentRandomIndex) {
				random = proxy.lodash.random(0, currentList.length);
			} else {
				break;
			}
		}
		randomList.push(random);
		currentRandomIndex = random;
		playSong(currentList[random]?.id, 'auto');
		return;
	}
	// 判断播放顺序，再决定播放上一首
	if (type === 'previous' && currentOrder.value === '2') {
		// 如果为随机播放则播放上一首随机播放的歌曲
		let randomIndex = randomList.indexOf(currentRandomIndex);
		currentRandomIndex = randomList[randomIndex - 1];
		if (randomIndex == 0) {
			playSong(currentList[randomList[0]]?.id, 'auto');
			return;
		}
		playSong(currentList[randomList[randomIndex - 1]]?.id, 'auto');
		return;
	}
	if (type === 'previous') {
		// 直接播放上一首
		playSong(currentList[index - 1]?.id, 'auto');
		return;
	}
	// 如果未找到则从第一首开始播放
	if (index < 0) {
		playSong(currentList[0]?.id, 'auto');
		return;
	} else if (type === 'next') {
		playSong(currentList[index + 1]?.id, 'auto');
	}
}

// 播放器音量初始化
function initVolume() {
	nextTick(() => {
		audio.value.volume = audioVolume.value / 100;
	});
}

// 改变播放器音量
watch(audioVolume, (newVal) => {
	nextTick(() => {
		audio.value.volume = newVal / 100;
	});
});

// 播放进度
let currentTime = ref('00:00'); // 当前播放时间
let progressValue = ref(0); // 进度条值
let isFinish = ref(false); // 是否播放结束
function getSongCurrentProgress() {
	currentTime.value = formatAudioTime(audio.value.currentTime); // 当前播放时间
	let formatCurrentTime = parseFloat(audio.value.currentTime.toFixed(2));
	lyricScroll(formatCurrentTime); // 歌词滚动
	progressValue.value = (audio.value.currentTime / audio.value.duration) * 100; // 进度条
	// 判断播放是否结束
	if (
		currentTime.value === player.currentSongInfo.duration ||
		progressValue.value === 100
	) {
		console.log('歌曲播放完毕...');
		player.changePlayStatus(false);
		isFinish.value = true;
		if (currentOrder.value === '3') return; // 循环播放停止自动下一首
		handleNextSong(plStore.currentPlaylist, player.currentSongInfo);
	}
}

// 是否播放结束
watch(isFinish, (newVal) => {
	if (newVal) player.changePlayStatus(false);
});

// 拖拽进度条
function dragProgressBar() {
	console.log('拖动了进度条...');
	if (!player.currentSongInfo.id) return;
	// 调整进度
	const newTime = parseFloat((progressValue.value * audio.value.duration) / 100).toFixed(
		6
	);
	audio.value.currentTime = newTime;
	if (newTime === 0.0) currentLyric.value = 0;
	lyricScroll(newTime);
	if (isFinish.value) {
		isFinish.value = false;
		audio.value.play(); // 播放音乐
	}
}

// 歌词滚动
let currentLyric = ref(0); // 当前歌词（行）
function lyricScroll(time) {
	for (let i in player.currentSongInfo.lyric) {
		let index = parseInt(i);
		if (!isNaN(player.currentSongInfo.lyric[i].schedule)) {
			if (time >= player.currentSongInfo.lyric[index].schedule) {
				currentLyric.value = index;
			}
		}
	}
}
// 切换高亮的歌词
watch(currentLyric, () => {
	let lyricUl = document.querySelector('.lyric');
	let lyricActive = document.querySelector('.lyricActive');
	if (lyricUl && lyricActive) {
		let offset = lyricActive.offsetTop - lyricUl.scrollTop - 20;
		lyricUl.style.transform = `translateY(-${offset}px)`;
	}
});
const currentSongInfo = computed(() => {
	return player.currentSongInfo;
});
// 切换歌曲时做的事
watch(
	currentSongInfo,
	() => {
		audio.value.src = currentSongInfo.value.url;
		audio.value.rossOrigin = 'anonymous';
		playerContainer.value.style.bottom = '0';
		currentLyric.value = 0;
		nextTick(() => {
			handlePlayPause();
		});
		showState.value = true;
		player.getSimilarSong();
	},
	{ deep: true }
);

// 显示/隐藏播放器
let playerContainer = ref(); // 播放器
let showState = ref(true);
function showAndHidden() {
	let playerBottom = playerContainer.value.style.bottom;
	// 修改 bottom 值
	if (playerBottom === '0px') {
		playerContainer.value.style.bottom = '-60px';
		showState.value = false;
	} else {
		playerContainer.value.style.bottom = '0';
		showState.value = true;
	}
}

// 显示播放页面
let showPlaySongPage = ref(false);
let playSongPage = ref(null); // 播放页面
function showPlayPage() {
	let width = playSongPage.value.style.width;
	let height = playSongPage.value.style.height;
	playSongPage.value.style.backgroundImage = `url(\' ${
		player.currentSongInfo.cover + '?param=500y500'
	} \')`;
	if (width === '0px' && height === '0px') {
		showPlaySongPage.value = true;
		playSongPage.value.style.width = '100%';
		playSongPage.value.style.height = '100%';
		playSongPage.value.style.opacity = '1';
		document.body.style.overflowY = 'hidden';
	} else {
		showPlaySongPage.value = false;
		playSongPage.value.style.width = '0px';
		playSongPage.value.style.height = '0px';
		playSongPage.value.style.opacity = '0';
		document.body.style.overflowY = 'scroll';
	}
}

function init() {
	initVolume();
}

onMounted(() => {
	init();
});
</script>

<style lang="scss" scoped>
// 播放器
.playerContainer {
	width: 100%;
	height: 60px;
	background-color: rgba(0, 0, 0, 0.6);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	position: fixed;
	left: 0;
	transition: bottom 0.3s;
	z-index: 2000;

	.player {
		height: 100%;
		margin: 0 auto;
		display: flex;
		align-items: center;

		// 控制切歌
		.controls {
			width: 140px;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: space-between;

			.iconfont {
				transition: all 0.3s;

				&:hover {
					filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5));
				}
			}
		}

		// 歌曲封面
		.songCover {
			width: 45px;
			height: 45px;
			background-color: $light-color;
			margin-left: 30px;
			overflow: hidden;

			img {
				width: 100%;
				height: 100%;
			}
		}

		// 播放进度
		.playProgress {
			width: 500px;
			height: 45px;
			margin-left: 8px;

			.songInfo,
			.progress {
				height: 50%;
				display: flex;
				align-items: center;
				justify-content: space-between;
			}

			// 歌曲信息
			.songInfo {
				width: 497px;
				color: #fff;
				font-size: 15px;
				margin-left: 3px;

				.left {
					width: 300px;
				}
			}

			// 进度条
			.progress {
				width: 495px;
				margin-left: 5px;
			}
		}

		// 其他操作
		.otherControls {
			width: 300px;
			height: 45px;
			margin-left: 20px;

			.list,
			.volume {
				width: 300px;
				height: 50%;
				display: flex;
				align-items: center;
			}

			.list {
				width: 180px;
				justify-content: right;

				.iconfont {
					margin-left: 10px;
				}
			}
		}

		// 音频可视化
		.audioView {
			width: 50px;
			height: 50px;

			canvas {
				width: 100%;
				height: 100%;
			}
		}
	}

	// 显示/隐藏
	.showAndHidden {
		width: 50px;
		height: 20px;
		position: absolute;
		background-color: rgba(0, 0, 0, 0.6);
		-webkit-backdrop-filter: blur(10px);
		backdrop-filter: blur(10px);
		right: 0;
		bottom: 60px;
		border-top-left-radius: 10px;
	}
}

// 播放页
.playSongPage {
	position: fixed;
	left: 0;
	bottom: 0;
	z-index: 99;
	transition: width 0.5s, height 0.5s, background 0.5s, opacity 0.3s;
	background-color: $light-color;
	background-size: cover;
	background-repeat: no-repeat;
	display: flex;
	align-items: center;
	justify-content: center;

	// 关闭播放页
	.close {
		position: absolute;
		right: 20px;
		top: 20px;
	}

	// 模糊遮罩
	.mask {
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.6);
		-webkit-backdrop-filter: blur(10px);
		backdrop-filter: blur(120px);
		position: absolute;
		left: 0;
		top: 0;
		z-index: -1;
	}

	// 歌词
	.lyricContainer {
		width: 850px;
		height: 600px;
		position: relative;

		// 歌曲封面
		.songCover {
			width: 260px;
			height: 260px;
			background-color: $light-color;
			text-align: center;
			position: absolute;
			left: 0;
			top: 0;
			z-index: 999;
			border: 2px solid $main-color;
			box-sizing: border-box;
			border-radius: 8px;
			box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);

			// 相似歌曲
			.similarSong {
				width: 100%;
				height: 300px;

				h3 {
					text-align: left;
					color: #fff;
					font-size: 17px;
					display: flex;
					align-items: center;
					justify-content: space-between;
				}

				ul {
					width: 100%;
					height: 100%;
					margin: 0;
					padding: 0;
					overflow-y: scroll;

					li {
						width: 100%;
						padding: 5px 0;
						display: flex;
						align-items: center;
						color: #fff;
						border-radius: 5px;
						font-size: 15px;

						&:hover {
							background-color: rgba(255, 255, 255, 0.1);
						}

						.singers,
						.name {
							margin: 0 3px;
						}

						img {
							width: 35px;
							height: 35px;
							margin: 0 6px;
						}
					}
				}
			}

			&::before {
				content: '';
				display: block;
				width: 25px;
				height: 25px;
				border-radius: 50%;
				background-color: #1a1a1a;
				-webkit-backdrop-filter: blur(10px);
				backdrop-filter: blur(10px);
				position: absolute;
				right: -12.5px;
				top: calc(50% - 12.5px);
				border-left: 2px solid $main-color;
			}

			img {
				width: 100%;
				height: 100%;
				border-radius: 5px;
			}
		}

		// 唱片
		.disc {
			width: 220px;
			height: 220px;
			border-radius: 50%;
			position: absolute;
			left: 150px;
			top: 20px;
			z-index: 1;
			overflow: hidden;
			animation: discRotate 10s infinite linear;
			background: url('@/assets/img/disc.png') no-repeat;
			background-size: 100% 100%;
			display: flex;
			align-items: center;
			justify-content: center;

			img {
				width: 70%;
				height: 70%;
				border-radius: 50%;
				border: 4px solid silver;
			}
		}

		// 歌曲信息
		.songInfoContainer {
			position: absolute;
			right: 0;
			top: 0;
			width: 450px;
			height: 100%;

			.songInfo {
				width: 100%;
				height: 100px;
				color: #fff;

				// 歌曲名称
				.songName {
					width: 100%;
					height: 50px;
					line-height: 50px;
					font-size: 28px;
				}

				// 专辑和歌手信息
				.singerAndAlbum {
					width: 100%;
					height: 50px;
					line-height: 50px;
					font-size: 16px;

					span {
						color: #c9c9c9;
					}

					div {
						width: 45%;
					}
				}

				// 歌词
				.lyricBox {
					width: 100%;
					height: 430px;
					margin: 0;
					padding: 0;
					overflow: hidden;

					ul {
						width: 100%;
						height: 100%;
						transition: transform 0.3s;
						margin: 0;
						padding: 0;

						li {
							width: 100%;
							padding: 5px 0;
							line-height: 30px;
							font-size: 17px;
							color: #fff;
							transition: font-size 0.3s, font-weight 0.3s;
						}
					}
				}
			}
		}
	}
}

.playPageActive {
	background-color: rgba(0, 0, 0, 0.3) !important;
}

.lyricActive {
	color: $main-color !important;
	font-size: 24px !important;
	font-weight: bold;
}

// 唱片旋转
@keyframes discRotate {
	from {
		transform: rotateZ(0);
	}

	to {
		transform: rotateZ(360deg);
	}
}

.discAnimationPaused {
	animation-play-state: paused !important;
}

:deep(.el-slider__button) {
	width: 10px;
	height: 10px;
	border: none;
}
</style>
